/*
 * CashDrawerReportDialog.java
 *
 * Created on August 24, 2006, 11:20 PM
 */
package com.floreantpos.ui.dialog;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;

import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;

import net.miginfocom.swing.MigLayout;

import org.apache.ecs.Document;
import org.apache.ecs.html.BR;
import org.apache.ecs.html.HR;
import org.apache.ecs.html.P;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;

import com.floreantpos.main.Application;
import com.floreantpos.model.DrawerPullReport;
import com.floreantpos.model.DrawerPullVoidTicketEntry;
import com.floreantpos.model.Terminal;
import com.floreantpos.model.User;
import com.floreantpos.model.dao.TerminalDAO;
import com.floreantpos.report.services.ReportService;
import com.floreantpos.swing.PosButton;
import com.floreantpos.ui.TitlePanel;
import java.text.DecimalFormatSymbols;
import java.util.Locale;

/**
 *
 * @author MShahriar
 */
public class DrawerPullReportDialog extends POSDialog {

  private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
  private DecimalFormat decimalFormat = new DecimalFormat("#,##0.00", new DecimalFormatSymbols(new Locale("pt", "BR")));

  private DrawerPullReport drawerPullReport;
  private Terminal terminal;

  public DrawerPullReportDialog(java.awt.Frame parent, boolean modal) {
    super(parent, modal);
    initComponents();
  }

  public void initialize() throws Exception {
    terminal = Application.getInstance().getTerminal();

    drawerPullReport = ReportService.buildDrawerPullReport();

    taReport.setContentType("text/html");
    taReport.setEditable(false);
    taReport.setMargin(new Insets(0, 10, 0, 10));
    taReport.setText(createReport());
    taReport.setCaretPosition(0);

    taReport.setPreferredSize(new Dimension(360, 100));
  }

  private void initComponents() {
    setLayout(new BorderLayout(5, 5));

    titlePanel1 = new TitlePanel();
    add(titlePanel1, BorderLayout.NORTH);

    taReport = new JEditorPane();
    taReport.setContentType("text/html");

    add(new JScrollPane(taReport));

    JPanel buttonPanel = new JPanel(new MigLayout("fill", "", "[fill, grow][]"));

    buttonPanel.add(new JSeparator(), "grow,span,wrap");
    buttonPanel.add(btnResetCashDrawer = new PosButton(com.floreantpos.POSConstants.REMOVE_DRAWER), "w 120, h 50, grow");
    buttonPanel.add(btnFinish = new PosButton(com.floreantpos.POSConstants.CLOSE), "w 120, h 50, grow");

    add(buttonPanel, BorderLayout.SOUTH);

    btnFinish.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        btnFinishActionPerformed();
      }
    });
    btnResetCashDrawer.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        btnResetCashDrawerActionPerformed();
      }
    });
  }

  private void btnResetCashDrawerActionPerformed() {
    int option = JOptionPane.showOptionDialog(this, com.floreantpos.POSConstants.REMOVE_DRAWER, com.floreantpos.POSConstants.CONFIRMATION, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
    if (option != JOptionPane.YES_OPTION) {
      return;
    }

    Application app = Application.getInstance();
    Terminal terminal = app.getTerminal();
    User user = Application.getCurrentUser();

    TerminalDAO dao = new TerminalDAO();
    try {
      Double drawerBalance = Double.valueOf(0);

      NumberSelectionDialog2 balanceDialog = new NumberSelectionDialog2();
      balanceDialog.setTitle(com.floreantpos.POSConstants.NEW_BALANCE_DRAWER);
      balanceDialog.setFloatingPoint(true);

      balanceDialog.pack();
      balanceDialog.open();

      if (balanceDialog.isCanceled()) {
        return;
      }

      drawerBalance = balanceDialog.getValue();

      dao.resetCashDrawer(drawerPullReport, terminal, user, drawerBalance);
      dispose();
    } catch (Exception e) {
      POSMessageDialog.showError(com.floreantpos.POSConstants.ERROR_WRITING, e);
    }
  }

  private void btnFinishActionPerformed() {
    dispose();
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
        new DrawerPullReportDialog(new javax.swing.JFrame(), true).setVisible(true);
      }
    });
  }

  private com.floreantpos.swing.PosButton btnFinish;
  private com.floreantpos.swing.PosButton btnResetCashDrawer;
  private javax.swing.JEditorPane taReport;
  private com.floreantpos.ui.TitlePanel titlePanel1;

  void createReportHeader(Document document) {
    P p = new P();
    p.addAttribute("align", "center");
    p.addElement(new BR());
    p.addElement(com.floreantpos.POSConstants.DRAWER_PULL);
    p.addElement(new BR());
    document.appendBody(p);
  }

  void createSectionHeader(Document document, String headerText) {
    P p = new P();
    p.addAttribute("align", "center");
    p.addElement(headerText);
    p.addElement(new HR());
    document.appendBody(p);
  }

  void addSeparator(Document document) {
    P p = new P();
    HR hr = new HR();
    hr.addAttribute("style", "border: dashed;");
    p.addElement(hr);
    document.appendBody(p);
  }

  void addTableSeparator(Table table) {
    TR tr = new TR();
    TD td = new TD();
    td.addAttribute("colspan", 2);
    td.addAttribute("align", "right");
    HR hr = new HR();
    hr.addAttribute("style", "border: dashed;");
    td.addElement(hr);
    tr.addElement(td);
    table.addElement(tr);
  }

  void addExceptionTableSeparator(Table table) {
    TR tr = new TR();
    TD td = new TD();
    td.addAttribute("colspan", 5);
    td.addAttribute("align", "right");
    HR hr = new HR();
    hr.addAttribute("style", "border: dashed;");
    td.addElement(hr);
    tr.addElement(td);
    table.addElement(tr);
  }

  void addTableRow(Table table, String column1, String coulmn2) {
    TR tr = new TR();
    tr.addElement(new TD().addElement(column1));
    tr.addElement(new TD().addAttribute("align", "right").addElementToRegistry(coulmn2));
    table.addElement(tr);
  }

  void addDiscountTableRow(Table table, String column1, String coulmn2) {
    TR tr = new TR();
    tr.addElement(new TD().addAttribute("style", "padding-left: 50px;").addElementToRegistry(column1));
    tr.addElement(new TD().addAttribute("align", "right").addElementToRegistry(coulmn2));
    table.addElement(tr);
  }

  void addExceptionTableRow(Table table, String column1, String coulmn2, String coulmn3, String coulmn4, String column5) {
    TR tr = new TR();
    TD td = new TD();
    td.addAttribute("valign", "top");
    td.addElement(column1);
    tr.addElement(td);

    td = new TD();
    td.addAttribute("valign", "top");
    td.addElement(coulmn2);
    tr.addElement(td);

    td = new TD();
    td.addAttribute("valign", "top");
    td.addAttribute("align", "right");
    td.addElement(coulmn3);
    tr.addElement(td);

    td = new TD();
    td.addAttribute("valign", "top");
    td.addAttribute("align", "right");
    td.addElement(coulmn4);
    tr.addElement(td);

    td = new TD();
    td.addAttribute("valign", "top");
    td.addAttribute("align", "right");
    td.addElement(column5);
    tr.addElement(td);

    table.addElement(tr);
  }

  public String createReport() throws Exception {
    Document document = new Document();

    Table table = null;

    createReportHeader(document);

    P p = new P();
    p.addElement(com.floreantpos.POSConstants.DATE + " : " + dateFormat.format(new Date()));
    document.appendBody(p);

    createSectionHeader(document, com.floreantpos.POSConstants.SALES);
    table = new Table();
    table.addAttribute("width", "100%");
    addTableRow(table, "+ " + com.floreantpos.POSConstants.SALES, decimalFormat.format(drawerPullReport.getTotalRevenue()));
    addTableRow(table, "+ " + com.floreantpos.POSConstants.SERVER_TIPS, decimalFormat.format(drawerPullReport.getChargedTips()));
    addTableSeparator(table);
    addTableRow(table, "= " + com.floreantpos.POSConstants.GROSS_SALES, decimalFormat.format(drawerPullReport.getGrossReceipts()));
    document.appendBody(table);

    document.appendBody(new BR());

    createSectionHeader(document, com.floreantpos.POSConstants.RECEIPTS);
    table = new Table();
    table.addAttribute("width", "100%");
    addTableRow(table, "+ " + com.floreantpos.POSConstants.CASH_TRANSACTION, decimalFormat.format(drawerPullReport.getCashReceiptAmount()));
    addTableRow(table, "+ " + com.floreantpos.POSConstants.CARD, decimalFormat.format(drawerPullReport.getCreditCardReceiptAmount()));
    addTableRow(table, "+ " + com.floreantpos.POSConstants.HANG, decimalFormat.format(drawerPullReport.getGiftCertReturnAmount()));
    addTableSeparator(table);
    addTableRow(table, "= " + com.floreantpos.POSConstants.TOTAL_AMOUNT_RECEIVED, decimalFormat.format(drawerPullReport.getCashReceiptAmount() + drawerPullReport.getCreditCardReceiptAmount() + drawerPullReport.getGiftCertReturnAmount()));
    document.appendBody(table);

    document.appendBody(new BR());

    createSectionHeader(document, com.floreantpos.POSConstants.SERVER_TIPS);
    table = new Table();
    table.addAttribute("width", "100%");
    addTableRow(table, "+ " + com.floreantpos.POSConstants.TIP_OPEN, decimalFormat.format(drawerPullReport.getOpenTips()));
    addTableRow(table, "- " + com.floreantpos.POSConstants.TIP_PAID, decimalFormat.format(drawerPullReport.getTipsPaid()));
    document.appendBody(table);

    document.appendBody(new BR());

    createSectionHeader(document, " " + com.floreantpos.POSConstants.CASH_BALANCE);
    table = new Table();
    table.addAttribute("width", "100%");
    addTableRow(table, com.floreantpos.POSConstants.CASH_TRANSACTION, decimalFormat.format(drawerPullReport.getCashReceiptAmount()));
    addTableRow(table, "- " + com.floreantpos.POSConstants.TIP_PAID, decimalFormat.format(drawerPullReport.getTipsPaid()));
    addTableRow(table, "- " + com.floreantpos.POSConstants.CAPITAL_PAY_OUT, decimalFormat.format(drawerPullReport.getPayOutAmount()));
    addTableRow(table, "+ " + com.floreantpos.POSConstants.INITIAL_BALANCE, decimalFormat.format(terminal.getOpeningBalance()));
    addTableRow(table, "- " + com.floreantpos.POSConstants.DRAWER_BLEED, decimalFormat.format(drawerPullReport.getDrawerBleedAmount()));
    addTableSeparator(table);
    addTableRow(table, "= " + com.floreantpos.POSConstants.TOTAL_DRAWER, decimalFormat.format(drawerPullReport.getCashToDeposit()));
    document.appendBody(table);

    createSectionHeader(document, com.floreantpos.POSConstants.EXCEPTION);
    createSectionHeader(document, com.floreantpos.POSConstants.CANCELLATIONS);
    table = new Table();
    table.addAttribute("width", "100%");
    addExceptionTableRow(table, com.floreantpos.POSConstants.CODE, com.floreantpos.POSConstants.PAY_OUT_REASON, " ", " ", com.floreantpos.POSConstants.AMOUNT);
    addExceptionTableSeparator(table);

    Set<DrawerPullVoidTicketEntry> voidTickets = drawerPullReport.getVoidTickets();
    if (voidTickets != null) {
      for (DrawerPullVoidTicketEntry entry : voidTickets) {
        addExceptionTableRow(table, String.valueOf(entry.getCode()), entry.getReason(), " ", " ", Application.formatNumber(entry.getAmount()));
      }
    }
    addExceptionTableSeparator(table);
    document.appendBody(table);

    table = new Table();
    table.addAttribute("width", "100%");
    addTableRow(table, com.floreantpos.POSConstants.CANCELLATIONS, decimalFormat.format(drawerPullReport.getTotalVoid()));

    document.appendBody(table);

    createSectionHeader(document, com.floreantpos.POSConstants.COUPON_DISCOUNT_EXPLORER);
    table = new Table();
    document.appendBody(table);
    table.addAttribute("width", "100%");
    addTableRow(table, com.floreantpos.POSConstants.TOTAL_DISCOUNTS, "");
    addDiscountTableRow(table, com.floreantpos.POSConstants.QUANTITY, String.valueOf(drawerPullReport.getTotalDiscountCount()));
    addDiscountTableRow(table, com.floreantpos.POSConstants.AMOUNT, Application.formatNumber(drawerPullReport.getTotalDiscountAmount()));
    addDiscountTableRow(table, com.floreantpos.POSConstants.SALES, Application.formatNumber(drawerPullReport.getTotalDiscountSales() + drawerPullReport.getTotalDiscountAmount()));

    return document.toString();
  }

  public void setTitle(String title) {
    titlePanel1.setTitle(title);
    super.setTitle(title);
  }
}
